/**
 * File Name	: GenericHibernateDao.java
 * Author		: 1340079:Adelwin
 * Create Date	: Apr 30, 2010:5:03:51 PM
 *
 */

package org.jampang.core.dao.impl;

import java.io.Serializable;
import java.util.Collection;
import java.util.List;

import org.hibernate.Criteria;
import org.hibernate.SessionFactory;
import org.hibernate.criterion.Example;
import org.hibernate.criterion.MatchMode;
import org.jampang.core.dao.IGenericHibernateDao;
import org.jampang.core.exception.GenericDaoException;
import org.jampang.core.model.BaseModel;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.orm.hibernate3.support.HibernateDaoSupport;

public class GenericHibernateDao<T extends BaseModel, ID extends Serializable> extends HibernateDaoSupport implements IGenericHibernateDao<T, ID> {

	protected Logger logger = LoggerFactory.getLogger(GenericHibernateDao.class);
	protected Class<? extends BaseModel> modelClass;

	public GenericHibernateDao(SessionFactory sessionFactory, Class<BaseModel> modelClass) {
		super.setSessionFactory(sessionFactory);
		this.setModelClass(modelClass);
	}

	protected void setModelClass(Class<? extends BaseModel> modelClass) {
		this.modelClass = modelClass;
	}

	protected Class<? extends BaseModel> getModelClass() {
		return modelClass;
	}

	@SuppressWarnings("unchecked")
	public T getById(ID id) throws GenericDaoException {
		T model = (T) this.getHibernateTemplate().get(this.modelClass, id);
		this.getHibernateTemplate().initialize(model);
		return model;
	}

	public List<T> getListByCriteria(T criteria) throws GenericDaoException {
		return getListByCriteria(criteria, -1, -1, false);
	}

	public List<T> getListByCriteria(T criteria, boolean wildcard) throws GenericDaoException {
		return getListByCriteria(criteria, -1, -1, wildcard);
	}

	public List<T> getListByCriteria(T criteria, int sizeLimit) throws GenericDaoException {
		return getListByCriteria(criteria, -1, sizeLimit, false);
	}

	public List<T> getListByCriteria(T criteria, int indexStart, int sizeLimit) throws GenericDaoException {
		return getListByCriteria(criteria, indexStart, sizeLimit, false);
	}

	public List<T> getListByCriteria(T criteria, int sizeLimit, boolean wildcard) throws GenericDaoException {
		return getListByCriteria(criteria, -1, sizeLimit, wildcard);
	}

	@SuppressWarnings("unchecked")
	public List<T> getListByCriteria(T criteria, int indexStart, int sizeLimit, boolean wildcard) throws GenericDaoException {
		Example criterion = Example.create(criteria).ignoreCase().excludeZeroes();
		if (wildcard == true)
			criterion.enableLike(MatchMode.ANYWHERE);
		Criteria hibernateCriteria = this.getSession().createCriteria(this.modelClass).add(criterion);
		if (indexStart >= 0)
			hibernateCriteria.setFirstResult(indexStart);
		if (sizeLimit >= 0)
			hibernateCriteria.setFetchSize(sizeLimit);
		return hibernateCriteria.list();
	}

	public void save(T domain) {
		getHibernateTemplate().saveOrUpdate(domain);
	}

	public void save(Collection<? extends T> domains) {
		for(T domain: domains) {
			save(domain);
		}
	}

	public void delete(T criterion) throws GenericDaoException {
		this.getHibernateTemplate().delete(criterion);
	}

}